home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / recvfax / auth.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  6KB  |  190 lines

  1. /*    $Header: /usr/people/sam/fax/recvfax/RCS/auth.c,v 1.10 1994/02/28 14:21:54 sam Rel $
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #include "defs.h"
  26.  
  27. #include <sys/socket.h>
  28. #include <netinet/in.h>
  29. #include <netdb.h>
  30. #include <arpa/inet.h>
  31.  
  32. static char*
  33. topdomain(char* h)
  34. {
  35.     register char* p;
  36.     char* maybe = NULL;
  37.     int dots = 0;
  38.  
  39.     for (p = h + strlen(h); p >= h; p--)
  40.     if (*p == '.') {
  41.         if (++dots == 2)
  42.         return (p);
  43.         maybe = p;
  44.     }
  45.     return (maybe);
  46. }
  47.  
  48. /*
  49.  * Check whether host h is in our local domain,
  50.  * defined as sharing the last two components of the domain part,
  51.  * or the entire domain part if the local domain has only one component.
  52.  * If either name is unqualified (contains no '.'),
  53.  * assume that the host is local, as it will be
  54.  * interpreted as such.
  55.  */
  56. static int
  57. local_domain(char* h)
  58. {
  59.     char localhost[80];
  60.     char* p1;
  61.     char* p2;
  62.  
  63.     localhost[0] = 0;
  64.     (void) gethostname(localhost, sizeof (localhost));
  65.     p1 = topdomain(localhost);
  66.     p2 = topdomain(h);
  67.     return (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2));
  68. }
  69.  
  70. extern int rexMatch(const char* pat,
  71.         const char* dotform, int dotlen,
  72.         const char* hostform, int hostlen);
  73.  
  74. void
  75. checkPermission()
  76. {
  77.     static int alreadyChecked = 0;
  78.     char dotform[1024], hostform[1024];
  79.     int dotlen, hostlen;
  80.     char* dotaddr;
  81.     struct sockaddr_in sin;
  82.     int sinlen;
  83.     FILE* db;
  84.  
  85.     if (alreadyChecked)
  86.     return;
  87.     alreadyChecked = 1;
  88.     sinlen = sizeof (sin);
  89.     if (getpeername(fileno(stdin), (struct sockaddr*)&sin, &sinlen) < 0) {
  90.     syslog(LOG_ERR, "getpeername: %m");
  91.     sendError("Can not get your network address.");
  92.     done(-1, "EXIT");
  93.     }
  94.     dotaddr = inet_ntoa(sin.sin_addr);
  95.     db = fopen(FAX_PERMFILE, "r");
  96.     if (db) {
  97.     struct hostent* hp;
  98.     char* hostname = NULL;
  99.     char line[1024];
  100.  
  101.     hp = gethostbyaddr(&sin.sin_addr, sizeof (sin.sin_addr),
  102.         sin.sin_family);
  103.     if (hp) {
  104.         /*
  105.          * If name returned by gethostbyaddr is in our domain,
  106.          * attempt to verify that we haven't been fooled by someone
  107.          * in a remote net; look up the name and check that this
  108.          * address corresponds to the name.
  109.          */
  110.         if (local_domain(hp->h_name)) {
  111.         strncpy(line, hp->h_name, sizeof (line) - 1);
  112.         line[sizeof (line) - 1] = '\0';
  113.         hp = gethostbyname(line);
  114.         if (hp) {
  115.             for (; hp->h_addr_list[0] != NULL; hp->h_addr_list++) {
  116.             if (memcmp(hp->h_addr_list[0], (caddr_t) &sin.sin_addr,
  117.               hp->h_length) == 0) {
  118.                 hostname = hp->h_name;    /* accept name */
  119.                 break;
  120.             }
  121.             }
  122.             if (hostname == NULL)
  123.             sendAndLogError(
  124.             "Your host address \"%s\" is not listed for host \"%s\".",
  125.                 dotaddr, hp->h_name);
  126.         } else
  127.             sendAndLogError("Could not find the address for \"%s\".",
  128.                line);
  129.         } else
  130.         hostname = hp->h_name;
  131.     } else
  132.         sendAndLogError(
  133.         "Can not map your network address (\"%s\") to a hostname",
  134.         dotaddr);
  135.     /*
  136.      * Now check the host name/address against
  137.      * the list of hosts that are permitted to
  138.      * submit jobs.
  139.      */
  140.     strcpy(dotform, userID);
  141.     strcat(dotform, "@");
  142.     strcat(dotform, dotaddr);
  143.     dotlen = strlen(dotform);
  144.     if (hostname != NULL) {
  145.         strcpy(hostform, userID);
  146.         strcat(hostform, "@");
  147.         strcat(hostform, hostname);
  148.         hostlen = strlen(hostform);
  149.     } else
  150.         hostlen = 0;
  151.     while (fgets(line, sizeof (line)-1, db)) {
  152.         char* cp = cp = strchr(line, '#');
  153.         if (cp || (cp = strchr(line, '\n')))
  154.         *cp = '\0';
  155.         /* trim off trailing white space */
  156.         for (cp = strchr(line, '\0'); cp > line; cp--)
  157.         if (!isspace(cp[-1]))
  158.             break;
  159.         *cp = '\0';
  160.         if (line[0] == '!') {
  161.         /*
  162.          * "!" in the first column means, disallow on match.
  163.          */
  164.         if (rexMatch(line+1, dotform, dotlen, hostform, hostlen))
  165.             break;
  166.         } else {
  167.         /*
  168.          * Hack for backwards compatibility; take pure host
  169.          * specification and form the regex ".*@<host>" to
  170.          * match against all users from that host.
  171.          */
  172.         if (strchr(line+0, '@') == NULL) {
  173.             char line1[1024];
  174.             strcpy(line1, ".*@");
  175.             strcat(line1, line+0);
  176.             if (rexMatch(line1, dotform, dotlen, hostform, hostlen))
  177.             return;
  178.         } else if (rexMatch(line+0, dotform, dotlen, hostform, hostlen))
  179.             return;
  180.         }
  181.     }
  182.     fclose(db);
  183.     } else
  184.     sendError("The server does not have a permissions file.");
  185.     syslog(LOG_ERR, "%s: Service refused", hostlen == 0 ? dotform : hostform);
  186.     sendError("You do not have permission to %s.",
  187.     "use the fax server from this host");
  188.     done(-1, "EXIT");
  189. }
  190.